#ifndef HJ_FRAME_STRUCTURE_BASE_NET_INCLUDE_CHTTPFILE_H_
#define HJ_FRAME_STRUCTURE_BASE_NET_INCLUDE_CHTTPFILE_H_
#include "CBaseNetHeader.h"
#include "mongoose.h"
/**
 *
 * Copyright(c), SuperHouse Co.,Ltd.
 * All rights reserved.
 *
 * @brief   mqtt 客服端封装
 * @note    -
 * @author  lth
 * @date    2021-12-18
 *
 */

BASENET_BEGIN_NAMESPACE

class BASENET_API CHttpFile
{
public:
	typedef enum _eStatusCode{
		CODE_DOWN_FILE_NONE = -1, 	// 未初始化状态
		CODE_DOWN_FILE_SUCCESS, 	// 下载文件成功
		CODE_DOWN_FILE_FAIL_NET, 		// 下载文件失败，没网
		CODE_DOWN_FILE_FAIL_URL,		// 下载文件失败，网址错误
		CODE_DOWN_FILE_FAIL_UNKNOWN		// 下载文件失败，未知错误
	}E_StatusCode;
public:

	/**
	 * 构造函数
	 *
	 * @note
	 * @return -
	 */
	CHttpFile();

	CHttpFile(unsigned long IoSize);

	/**
	 * 析构函数
	 *
	 * @note
	 * @return -
	 */
	~CHttpFile();

private:
	/**
	 * 运行http请求
	 *
	 * @note
	 * @return -
	 */
	void requireRun();

	/**
	 * 发送请求数据
	 *
	 * @note
	 * @return -
	 */
	void sendReuireData(struct mg_connection *c, int ev, void *ev_data);


	/**
	 * 解析接受数据
	 *
	 * @note
	 * @return -
	 */
	void recvReuireData(struct mg_connection *c, int ev, void *ev_data);

	/**
	 * 块数据接受，大文件需要处理
	 *
	 * @note
	 * @return -
	 */
	void recvReuireChunkData(struct mg_connection *c, int ev, void *ev_data, bool isCHunk = true);

	/**
	 * 获取请求方法
	 *
	 * @note
	 * @return -
	 */
	const char *getHttpMethod();

public:

	/**
	 * http pool回调
	 *
	 * @note
	 * @return -
	 */
	void __httpClientCB(struct mg_connection *c, int ev, void *ev_data);

	/**
	 * 定时器回调
	 *
	 * @note
	 * @return -
	 */
	void __httpConTimeOutCB();

	// 获取文件扩展名
	static std::string getContentFileType(const std::string& contentType);

public:

	/**
	 * 清除http请求
	 *
	 * @note
	 * @return -
	 */
	void cancelReuire();

	/**
	 * 初始化连接参数
	 *
	 * @note
	 * @return -
	 */
	 void initContParm(int method,string url,int conTimeout=3,int recvTimeout=5);

	/**
	 * 初始化数据参数
	 *
	 * @note
	 * @return -
	 */
	 void initDataParm(MAP_PARAMS *parm,MAP_PARAMS *extra_headers=NULL,string fileName="",string filePath="", bool isAutoFileName = false, bool isAutoFileType = false);

	/**
	 * 发起请求
	 *
	 * @note
	 * @return -
	 */
	 void initTls(struct mg_tls_opts *sTlsOpts);

	/**
	 * 发起请求
	 *
	 * @note
	 * @return -
	 */
	 bool startReuire();

	 // 设置当前为下载文件
	 void setCurrentDownFile(bool status){m_isDownFile=status;}

	 // 获取返回内容
	 string getRetBody(){return m_retBody;}

	 // 获取下载文件名
	 string getDownFilePath() { return m_sFilePath;}

private:
	// 连接超时
	int m_iConTime;
	// 接收超时
	int m_iRecvTime;
	// 请求头
	MAP_PARAMS *m_pHeadParams;
	// 请求参数
	MAP_PARAMS *m_pParms;
	// 请求内容（文件名）
	string m_sFileName;
	// 请求内容（文件路径）
	string m_sFilePath;
	// 请求地址
	string m_sUrl;
	// 请求方法
	int m_sMethod;
	// 运行状态
	bool m_bRunStatus;
	// 计算时间
	unsigned long m_lPrev_second;
	// 上传或下载的文件
	FILE *		m_fp;
	// 要下载或上传的文件总大小
	long long 	m_fileTotalSize;
	// 已下载或已上传的文件总大小
	long long 	m_fileCurrentSize;
	// 文件下载或上传状态
	bool		m_fileDownOrUpStatus;
	// 当前是下载文件还是上传文件
	bool 		m_isDownFile;
	bool 		m_isHandleBlockData;
	// 返回body
	string 		m_retBody;
	// 自动补全文件扩展名
	bool		m_isAutoFileType;
	// 自动取名文件
	bool		m_isAutoFileName;

private:
	// 连接超时计数
	int m_iConTimeTmp;
	// 连接文件
	struct mg_connection *m_sCon;
	// 连接管理
	struct mg_mgr m_sMgr;
	// ssl配置
	struct mg_tls_opts m_sTlsOpts;

public:
	// 下载文件
	static int downFile(string url,const string savePath,int conTimeout=3,int recvTimeout=10);

	// 下载文件
	static int downFile(unsigned long IoSize, const string &url,const string savePath,int conTimeout=3,int recvTimeout=10);

	static string downFileToDir(unsigned long IoSize, const string &url,const string saveDir, bool isautoFileType = true, int conTimeout=3,int recvTimeout=10);

	// 上传文件
	static string pullFile(int method,const char *url,MAP_PARAMS *headParams,string fileName,string filePath,int conTimeout=3,int recvTimeout=60);


};


BASENET_END_NAMESPACE





#endif // HJ_FRAME_STRUCTURE_BASE_NET_INCLUDE_CHTTPFILE_H_
